package com.example.everying.framework.pay.service;

import com.example.everying.config.WeChatConfig;
import com.example.everying.model.dto.pay.TransferCallbackResult;
import com.example.everying.utils.WeChatUtil;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Slf4j
@Component
public class WechatPayServiceImpl implements WechatPayService {

    @Autowired
    private WeChatConfig weChatConfig;

    /**
     * 微信支付下单 创建订单
     *
     * @param fen         订单总金额，单位为分。
     * @param description 商品描述
     * @param outTradeNo  商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一，长度[6-32]
     * @param openId      用户在直连商户appid下的唯一标识。 下单前需获取到用户的Openid
     * @return 下单结果
     */
    @Override
    public PrepayWithRequestPaymentResponse createOrder(Integer fen, String description, String outTradeNo, String openId) {
        //这里使用JSAPI支付模块，其他模块大同小异，使用其他支付模块，就用其他支付模块包内的对象
        //使用Jsapi服务扩展对象：com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension
        JsapiServiceExtension serviceExtension = new JsapiServiceExtension.Builder().config(weChatConfig.getConfig()).build();
        //构建对象com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest，并设置必填参数
        //其他参数请移步[官方接口文档:https://pay.weixin.qq.com/doc/v3/merchant/4012525057]
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(fen);
        request.setAmount(amount);
        request.setAppid(weChatConfig.getAppId());
        request.setMchid(weChatConfig.getMerchantId());
        request.setDescription(description);
        request.setNotifyUrl(weChatConfig.getPayNotifyUrl());
        log.info("回调地址：{}", weChatConfig.getPayNotifyUrl());
        request.setOutTradeNo(outTradeNo);
        Payer payer = new Payer();
        payer.setOpenid(openId);
        request.setPayer(payer);
        //发送请求
        log.info("微信下单发送HTTP请求，请求参数：{}", request);
        return serviceExtension.prepayWithRequestPayment(request);
    }

    /**
     * 商户订单号查询订单
     *
     * @param outTradeNo 商户订单号
     * @return com.wechat.pay.java.service.payments.model.Transaction
     */
    @Override
    public Transaction queryOrderByOutTradeNo(String outTradeNo) {
        JsapiServiceExtension serviceExtension = new JsapiServiceExtension.Builder().config(weChatConfig.getConfig()).build();

        QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
        request.setMchid(weChatConfig.merchantId);
        request.setOutTradeNo(outTradeNo);

        return serviceExtension.queryOrderByOutTradeNo(request);
    }

    /**
     * 下单支付回调
     *
     * @param request HttpServletRequest
     * @return 通知结果
     */
    @Override
    public Transaction payCallback(HttpServletRequest request) throws IOException {

        RequestParam requestParam = WeChatUtil.handleNodifyRequestParam(request);

        //构建通知解析器com.wechat.pay.java.core.notification.NotificationParser
        NotificationParser parser = weChatConfig.notificationParser();
        //验签、解密并转换成 com.wechat.pay.java.service.payments.model.Transaction
        return parser.parse(requestParam, Transaction.class);//获取通知结果
    }

}
